package com.wlyy.his.ali.auth;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

import javax.annotation.Resource;

/**
 *
 * 支付宝小程序有关额接口调用
 * @Author zhouyanhui
 *
 **/
@EnableConfigurationProperties(AliAuthProperties.class)
public class AliMiniAuthUtil {
    public static final Logger LOGGER = LoggerFactory.getLogger(AliMiniAuthUtil.class);

    private static final String URL = "https://openapi.alipay.com/gateway.do";
    private static final String AUTHORIZATION_CODE = "authorization_code";
    private static final String REFRESH_TOKEN = "refresh_token";
    private static final String FORMAT = "json";
    private static final String CHARSET = "UTF-8";
    private static final String SIGN_TYPE = "RSA2";
//    private static final String ENCRYPT_TYPE = "AES";

    @Resource
    private AliAuthProperties aliAuthProperties;


    /**
     * 获取用户 userId 以及AccessToken
     * @param authCode 前端获取到的授权码
     */
    public AlipaySystemOauthTokenResponse getAccessToken(String authCode) {
        return handle(authCode, AUTHORIZATION_CODE);
    }

    /**
     *
     * 刷新 AccessToken
     * @param refreshToken refreshToken
     *
     */
    public AlipaySystemOauthTokenResponse refreshToken(String refreshToken) {
        return handle(refreshToken, REFRESH_TOKEN);
    }

    /**
     * 调用支付宝获取用户信息的接口
     *
     * @param accessToken accessToken
     * @return AlipayUserInfoShareResponse
     */
    public AlipayUserInfoShareResponse getUserInfo(String accessToken) {
        AlipayClient alipayClient = aliAuthorization();
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        try {
            AlipayUserInfoShareResponse response = alipayClient.certificateExecute(request, accessToken);
            if (response.isSuccess()) {
                return response;
            }else{
                LOGGER.error("获取支付宝小程序用户信息失败: code: {} ,msg: {}",response.getCode(),response.getMsg());
            }
        } catch (AlipayApiException e) {
            LOGGER.error("获取支付宝小程序用户信息发生故障",e);
        }
        return null;

    }

//    /**
//     * @param encryptContent 前端获取过来的数据
//     * @param encryptKey     支付宝小程序AES秘钥
//     * @param publicKey      支付宝的公钥
//     * @return
//     * @ToDo 获取支付宝用户的手机号
//     */
//    public static String decryptor(String encryptContent, String encryptKey, String publicKey) {
//        String telephone = "";
//        try {
//            Map<String, String> openapiResult = JSON.parseObject(encryptContent,
//                    new TypeReference<Map<String, String>>() {
//                    },
//                    Feature.OrderedField);
//            String signType = StringUtils.defaultIfBlank(openapiResult.get("sign_type"), SIGN_TYPE);
//            String charset = StringUtils.defaultIfBlank(openapiResult.get("charset"), CHARSET);
//            String encryptType = StringUtils.defaultIfBlank(openapiResult.get("encrypt_type"), ENCRYPT_TYPE);
//            String sign = openapiResult.get("sign");
//            String content = openapiResult.get("response");
//
////                        LOGGER.info(String.format("准备验签和解密，sign=[%s], signType=[%s], encryptType=[%s], encryptContent=[%s]", sign, signType, encryptType, encryptContent));
//
//            //如果密文的
//            boolean isDataEncrypted = !content.startsWith("{");
//            //2. 验签
//            String signContent = content;
//            //如果是加密的报文则需要在密文的前后添加双引号
//            if (isDataEncrypted) {
//                signContent = "\"" + signContent + "\"";
//            }
//
//            try {
//
//                boolean signCheckPass = AlipaySignature.rsaCheck(signContent, sign, publicKey, charset, signType);
//                if (!signCheckPass) {
//                    System.out.println("验签失败，encryptContent="+encryptContent);
//                    //验签不通过（异常或者报文被篡改），终止流程（不需要做解密）
////                                        LOGGER.error("验签失败，encryptContent={}", encryptContent);
//                }
//            } catch (AlipayApiException e) {
//                System.out.println("验签异常，encryptContent="+encryptContent);
//                e.printStackTrace();
//                //验签异常, 日志
////                                LOGGER.error("验签异常，encryptContent={}", encryptContent, e);
//            }
//
//            //3. 解密
//            if (isDataEncrypted) {
//                try {
//                    telephone = AlipayEncrypt.decryptContent(content, encryptType, encryptKey, charset);
//                } catch (AlipayApiException e) {
//                    //解密异常, 日志
////                                        LOGGER.error("解密异常，encryptContent={}", encryptContent, e);
//                }
//            } else {
//                telephone = content;
//            }
//        } catch (Exception e) {
////                        LOGGER.error("验签解密异常，encryptContent={}",encryptContent, e);
//        }
//        return telephone;
//    }


    /**
     * 支付宝授权 服务端获取 access_token、user_id以及刷新access_token的公用方法
     *
     * @param code 授权码
     * @param grantType 类型
     * @return AlipaySystemOauthTokenResponse
     */
    private AlipaySystemOauthTokenResponse handle(String code,String grantType) {
        AlipayClient alipayClient = aliAuthorization();
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType(grantType);
        if (AUTHORIZATION_CODE.equals(grantType)) {
            request.setCode(code);
        } else if (REFRESH_TOKEN.equals(grantType)) {
            request.setRefreshToken(code);
        }

        try {
            AlipaySystemOauthTokenResponse response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                System.out.println("userId:   "+response.getUserId());
                System.out.println("access_token:   "+response.getAccessToken());
                System.out.println("rt:   "+response.getRefreshToken());
                return response;
            }else{
                LOGGER.info("授权失败,{}",response.getCode());
            }
        } catch (AlipayApiException e) {
            LOGGER.info("授权调用支付宝授权接口异常：{}",e.getMessage(),e);
        }
        return null;

    }


    /**
     * 设置调用支付宝接口的参数
     * @return AlipayClient
     */
    private AlipayClient aliAuthorization() {
        /* 初始化 **/
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        /* 支付宝网关 **/
        certAlipayRequest.setServerUrl(URL);
        /* 应用id，如何获取请参考：https://opensupport.alipay.com/support/helpcenter/190/201602493024 **/
        certAlipayRequest.setAppId(aliAuthProperties.getAppId());
        /* 应用私钥, 如何获取请参考：https://opensupport.alipay.com/support/helpcenter/207/201602471154?ant_source=antsupport **/
        certAlipayRequest.setPrivateKey(aliAuthProperties.getPrivateKey());
        /* 应用公钥证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setCertPath(aliAuthProperties.getCertPath());
        /* 支付宝公钥证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setAlipayPublicCertPath(aliAuthProperties.getAlipayPublicCertPath());
        /* 支付宝根证书路径，下载后保存位置的绝对路径 **/
        certAlipayRequest.setRootCertPath(aliAuthProperties.getRootCertPath());
        /* 设置签名类型 **/
        certAlipayRequest.setSignType(SIGN_TYPE);
        /* 设置请求格式，固定值json **/
        certAlipayRequest.setFormat(FORMAT);
        /* 设置编码格式 **/
        certAlipayRequest.setCharset(CHARSET);
        AlipayClient alipayClient = null;
        try {
            alipayClient = new DefaultAlipayClient(certAlipayRequest);
        } catch (AlipayApiException e) {
            LOGGER.error("设置alipayClient失败",e);
        }
        return alipayClient;
    }
}

